package com.supermap.panes;

import com.supermap.Helper;
import com.supermap.MainFrame;
import com.supermap.analyst.spatialanalyst.OverlayAnalyst;
import com.supermap.analyst.spatialanalyst.OverlayAnalystOutputType;
import com.supermap.analyst.spatialanalyst.OverlayAnalystParameter;
import com.supermap.consts.AttrConsts;
import com.supermap.data.*;
import com.supermap.dialogs.OverlayFieldsSettingDialog;
import com.supermap.dialogs.ProcessBarDialog;
import com.supermap.panes.advance.SettingPane;

import javax.swing.*;
import java.awt.*;

public class OverlayAnalystSettingPane extends SettingPane {
    private JComboBox<String> srcDatasourceCmb;
    private JComboBox<String> srcDatasetCmb;
    private JComboBox<String> overlayDatasourceCmb;
    private JComboBox<String> overlayDatasetCmb;
    private JComboBox<String> resultDatasourceCmb;
    private JComboBox<String> overlayAnalystModeCmb;
    private JCheckBox isSupportOverlayInLayerCbx;
    private JTextField toleranceTxt;
    private JTextField resultDatasetTxt;

    private ProcessBarDialog processBarDialog;
    private SteppedListener steppedListener;

    private Workspace workspace;
    private String[] selectedSrcFields;
    private String[] selectedOverlayFields;

    public OverlayAnalystSettingPane(Workspace workspace) {
        super("叠加分析", new Object[]{workspace});
    }

    @Override
    protected void initializeArgs(Object[] args) {
        workspace = (Workspace) args[0];
        steppedListener = steppedEvent -> {
            int percent = steppedEvent.getPercent();
            processBarDialog.setValue(percent);
            if (percent == 100) {
                processBarDialog.setVisible(false);
                JOptionPane.showMessageDialog(processBarDialog, "叠加分析完成！", "叠加分析", JOptionPane.INFORMATION_MESSAGE);
            }
        };
        OverlayAnalyst.addSteppedListener(steppedListener);
    }

    @Override
    protected void initializeCore() {
        super.confirmBtn.setText("分析");

        // 叠加分析参数
        JPanel centerPanel = new JPanel();
        centerPanel.setLayout(new GridBagLayout());

        JLabel overlayAnalystModeLbl = new JLabel("叠加分析算子: ");
        centerPanel.add(overlayAnalystModeLbl, new GridBagConstraints(0, 0, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 0, 2, 0), 0, 0));

        overlayAnalystModeCmb = new JComboBox<>();
        overlayAnalystModeCmb.addItem("裁剪");
        overlayAnalystModeCmb.addItem("合并");
        overlayAnalystModeCmb.addItem("擦除");
        overlayAnalystModeCmb.addItem("求交");
        overlayAnalystModeCmb.addItem("同一");
        overlayAnalystModeCmb.addItem("对称差");
        overlayAnalystModeCmb.addItem("更新");
        centerPanel.add(overlayAnalystModeCmb, new GridBagConstraints(1, 0, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 0, 2, 0), 0, 0));


        JPanel srcPanel = new JPanel();
        srcPanel.setBorder(BorderFactory.createTitledBorder("源数据"));
        srcPanel.setLayout(new GridBagLayout());
        centerPanel.add(srcPanel, new GridBagConstraints(0, 1, 2, 2, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 0, 2, 0), 0, 0));


        JLabel srcDatasourceLbl = new JLabel("源数据: ");
        srcPanel.add(srcDatasourceLbl, new GridBagConstraints(0, 0, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        srcDatasourceCmb = new JComboBox<>();
        Datasources datasources = workspace.getDatasources();
        if (datasources.getCount() > 0) {
            for (int i = 0; i < datasources.getCount(); i++) {
                Datasource datasource = datasources.get(i);
                srcDatasourceCmb.addItem(datasource.getAlias());
            }
            srcDatasourceCmb.setSelectedIndex(0);
        }
        srcDatasourceCmb.addItemListener(e -> {
            String selectedDatasourceName = (String) e.getItem();
            Datasource datasource = datasources.get(selectedDatasourceName);
            loadDatasetNames(datasource, srcDatasetCmb);
        });
        srcPanel.add(srcDatasourceCmb, new GridBagConstraints(1, 0, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JLabel srcDatasetLbl = new JLabel("数据集: ");
        srcPanel.add(srcDatasetLbl, new GridBagConstraints(0, 1, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        srcDatasetCmb = new JComboBox<>();
        if (srcDatasourceCmb.getItemCount() > 0) {
            String selectedDatasourceName = (String) srcDatasourceCmb.getSelectedItem();
            Datasource datasource = datasources.get(selectedDatasourceName);
            loadDatasetNames(datasource, srcDatasetCmb);
        }
        srcPanel.add(srcDatasetCmb, new GridBagConstraints(1, 1, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));


        JPanel overlayPanel = new JPanel();
        overlayPanel.setBorder(BorderFactory.createTitledBorder("叠加数据"));
        overlayPanel.setLayout(new GridBagLayout());
        centerPanel.add(overlayPanel, new GridBagConstraints(0, 3, 2, 2, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 0, 2, 0), 0, 0));

        JLabel overlayDatasourceLbl = new JLabel("源数据: ");

        overlayPanel.add(overlayDatasourceLbl, new GridBagConstraints(0, 1, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        overlayDatasourceCmb = new JComboBox<>();
        if (datasources.getCount() > 0) {
            for (int i = 0; i < datasources.getCount(); i++) {
                Datasource datasource = datasources.get(i);
                overlayDatasourceCmb.addItem(datasource.getAlias());
            }
            overlayDatasourceCmb.setSelectedIndex(0);
        }
        overlayDatasourceCmb.addItemListener(e -> {
            String selectedDatasourceName = (String) e.getItem();
            Datasource datasource = datasources.get(selectedDatasourceName);
            loadDatasetNames(datasource, overlayDatasetCmb);
        });
        overlayPanel.add(overlayDatasourceCmb, new GridBagConstraints(1, 1, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JLabel overlayDatasetLbl = new JLabel("数据集: ");
        overlayPanel.add(overlayDatasetLbl, new GridBagConstraints(0, 2, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        overlayDatasetCmb = new JComboBox<>();
        if (overlayDatasourceCmb.getItemCount() > 0) {
            String selectedDatasourceName = (String) overlayDatasourceCmb.getSelectedItem();
            Datasource datasource = datasources.get(selectedDatasourceName);
            loadDatasetNames(datasource, overlayDatasetCmb);
        }
        overlayPanel.add(overlayDatasetCmb, new GridBagConstraints(1, 2, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JPanel resultPanel = new JPanel();
        resultPanel.setBorder(BorderFactory.createTitledBorder("结果数据"));
        resultPanel.setLayout(new GridBagLayout());
        centerPanel.add(resultPanel, new GridBagConstraints(0, 5, 2, 4, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(2, 0, 2, 0), 0, 0));

        JLabel resultDatasourceLbl = new JLabel("源数据: ");
        resultPanel.add(resultDatasourceLbl, new GridBagConstraints(0, 0, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        resultDatasourceCmb = new JComboBox<>();
        if (datasources.getCount() > 0) {
            for (int i = 0; i < datasources.getCount(); i++) {
                Datasource datasource = datasources.get(i);
                resultDatasourceCmb.addItem(datasource.getAlias());
            }
            resultDatasourceCmb.setSelectedIndex(0);
        }
        resultPanel.add(resultDatasourceCmb, new GridBagConstraints(1, 0, 2, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JLabel resultDatasetLbl = new JLabel("数据集: ");
        resultPanel.add(resultDatasetLbl, new GridBagConstraints(0, 1, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        resultDatasetTxt = new JTextField();
        Object srcDatasourceCmbSelectedItem = srcDatasourceCmb.getSelectedItem();
        if (srcDatasourceCmbSelectedItem != null) {
            Datasource srcDatasource = datasources.get((String) srcDatasourceCmbSelectedItem);
            String resultDatasetName = srcDatasource.getDatasets().getAvailableDatasetName("result_OverlayAnalyst");
            resultDatasetTxt.setText(resultDatasetName);
        }
        resultPanel.add(resultDatasetTxt, new GridBagConstraints(1, 1, 1, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JButton resultFieldsSetBtn = new JButton("字段设置");
        resultFieldsSetBtn.addActionListener(e -> {
            DatasetVector srcDataset = getSelectedDatasetVector(datasources, srcDatasourceCmb, srcDatasetCmb);
            if (srcDataset == null) {
                return;
            }
            DatasetVector overlayDataset = getSelectedDatasetVector(datasources, overlayDatasourceCmb, overlayDatasetCmb);
            if (overlayDataset == null) {
                return;
            }

            OverlayFieldsSettingDialog fieldsSettingDialog = new OverlayFieldsSettingDialog((Frame) getRootPane().getParent(), "字段设置", true, srcDataset.getFieldInfos(), overlayDataset.getFieldInfos());
            fieldsSettingDialog.setVisible(true);
            selectedSrcFields = fieldsSettingDialog.getSelectedSrcFields();
            selectedOverlayFields = fieldsSettingDialog.getSelectedOverlayFields();
            fieldsSettingDialog.dispose();
        });
        resultPanel.add(resultFieldsSetBtn, new GridBagConstraints(2, 1, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JLabel toleranceLbl = new JLabel("容限");
        resultPanel.add(toleranceLbl, new GridBagConstraints(0, 2, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        toleranceTxt = new JTextField();
        toleranceTxt.setText("0.00036");
        resultPanel.add(toleranceTxt, new GridBagConstraints(1, 2, 2, 1, 10, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JLabel unitLbl = new JLabel("度");
        resultPanel.add(unitLbl, new GridBagConstraints(2, 2, 1, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        JPanel assistancePanel = new JPanel();
        assistancePanel.setLayout(new GridLayout(1, 4));

        isSupportOverlayInLayerCbx = new JCheckBox("支持面内自交叠");
        assistancePanel.add(isSupportOverlayInLayerCbx);

        resultPanel.add(assistancePanel, new GridBagConstraints(0, 3, 3, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, Helper.DefaultInsets, 0, 0));

        mainPanel.add(centerPanel);
    }

    @Override
    protected void doConfirm() {
        Datasources datasources = workspace.getDatasources();
        DatasetVector srcDataset = getSelectedDatasetVector(datasources, srcDatasourceCmb, srcDatasetCmb);
        if (srcDataset == null) {
            return;
        }
        DatasetVector overlayDataset = getSelectedDatasetVector(datasources, overlayDatasourceCmb, overlayDatasetCmb);
        if (overlayDataset == null) {
            return;
        }

        OverlayAnalystParameter overlayAnalystParameter = new OverlayAnalystParameter();
        overlayAnalystParameter.setSupportOverlapInLayer(isSupportOverlayInLayerCbx.isSelected());
        if (selectedSrcFields != null) {
            overlayAnalystParameter.setSourceRetainedFields(selectedSrcFields);
        }
        if (selectedOverlayFields != null) {
            overlayAnalystParameter.setOperationRetainedFields(selectedOverlayFields);
        }
        overlayAnalystParameter.setPreprocess(true);
        overlayAnalystParameter.setTolerance(Double.parseDouble(toleranceTxt.getText()));

        if (processBarDialog == null) {
            processBarDialog = new ProcessBarDialog((Frame) getRootPane().getParent(), "叠加分析", true);
        }

        switch (overlayAnalystModeCmb.getSelectedIndex()) {
            // 裁剪
            case 0:
                FieldInfos fieldInfos = srcDataset.getFieldInfos();
                int count = fieldInfos.getCount();
                selectedSrcFields = new String[count];
                for (int i = 0; i < count; i++) {
                    selectedSrcFields[i] = fieldInfos.get(i).getName();
                }
                overlayAnalystParameter.setSourceRetainedFields(selectedSrcFields);
                overlayAnalystParameter.setOutputType(srcDataset.getType() == DatasetType.POINT || overlayDataset.getType() == DatasetType.POINT
                        ? OverlayAnalystOutputType.POINT : OverlayAnalystOutputType.INPUT);

                // 新建叠加数据集
                Datasets datasets0 = srcDataset.getDatasource().getDatasets();
                String resultDatasetClipName = datasets0.getAvailableDatasetName(resultDatasetTxt.getText());
                DatasetVectorInfo datasetVectorInfoClip = new DatasetVectorInfo();
                datasetVectorInfoClip.setType(srcDataset.getType());
                datasetVectorInfoClip.setName(resultDatasetClipName);
                datasetVectorInfoClip.setEncodeType(EncodeType.NONE);
                DatasetVector resultDatasetClip = datasets0.create(datasetVectorInfoClip);

                new Thread(() -> {
                    if (OverlayAnalyst.clip(srcDataset, overlayDataset, resultDatasetClip, overlayAnalystParameter)) {
                        Helper.showDatasetVectorsComparison("叠加分析结果", srcDataset, resultDatasetClip, (MainFrame) getRootPane().getParent());
                    } else {
                        JOptionPane.showMessageDialog(getRootPane().getParent(), "叠加分析失败!", "叠加分析", JOptionPane.ERROR_MESSAGE);
                    }
                }).start();
                processBarDialog.setVisible(true);
                break;
            // 合并
            case 1:
                break;
            // 擦除
            case 2:
                break;
            // 求交
            case 3:
                overlayAnalystParameter.setOutputType(OverlayAnalystOutputType.INPUT);

                // 新建叠加数据集
                Datasets datasets = srcDataset.getDatasource().getDatasets();
                String resultDatasetUnionName = datasets.getAvailableDatasetName(resultDatasetTxt.getText());
                DatasetVectorInfo datasetVectorInfoUnion = new DatasetVectorInfo();
                datasetVectorInfoUnion.setType(srcDataset.getType());
                datasetVectorInfoUnion.setName(resultDatasetUnionName);
                datasetVectorInfoUnion.setEncodeType(EncodeType.NONE);
                DatasetVector resultDatasetUnion = datasets.create(datasetVectorInfoUnion);

                new Thread(() -> OverlayAnalyst.union(srcDataset, overlayDataset, resultDatasetUnion, overlayAnalystParameter)).start();
                processBarDialog.setVisible(true);
                break;
            // 同一
            case 4:
                break;
            // 对称差
            case 5:
                break;
            // 更新
            case 6:
                break;
            default:
                break;
        }
    }

    @Override
    protected void doClose() {
        OverlayAnalyst.removeSteppedListener(steppedListener);
        if (processBarDialog != null) {
            processBarDialog.dispose();
        }
    }

    private DatasetVector getSelectedDatasetVector(Datasources datasources, JComboBox<String> srcDatasourceCmb, JComboBox<String> srcDatasetCmb) {
        String srcDatasourceName = (String) srcDatasourceCmb.getSelectedItem();
        if (srcDatasourceName == null || srcDatasourceName.equals(AttrConsts.EMPTY)) {
            return null;
        }
        Datasource srcDatasource = datasources.get(srcDatasourceName);
        String srcDatasetName = (String) srcDatasetCmb.getSelectedItem();
        if (srcDatasetName == null || srcDatasetName.equals(AttrConsts.EMPTY)) {
            return null;
        }
        return (DatasetVector) srcDatasource.getDatasets().get(srcDatasetName);
    }

    private void loadDatasetNames(Datasource datasource, JComboBox<String> datasetCmb) {
        datasetCmb.removeAll();
        if (datasource != null) {
            Datasets datasets = datasource.getDatasets();
            if (datasets.getCount() > 0) {
                for (int i = 0; i < datasets.getCount(); i++) {
                    Dataset dataset = datasets.get(i);
                    if (dataset instanceof DatasetVector) {
                        datasetCmb.addItem(dataset.getName());
                    }
                }
            }
        }
    }
}
